// i.d(t, { s: () => l, n: () => ExpiringResource })

import funcUtil from "./func.util"
import Logger from "./Logger"

import OpenDeferred from "./OpenDeferred"
function runAllCallBack(e, callback) {
  if (null !== e && "object" == typeof e) for (const i in e) callback(e[i], i, e), runAllCallBack(e[i], callback)
}
const a = new Logger("expiring-resource")
export function setOnStateFunc(e, t) {
  runAllCallBack(e, e => {
    e instanceof ExpiringResource && (e.onStale = t)
  })
}
export default class ExpiringResource {
  value: any
  validUntil: any
  refreshPromise: OpenDeferred | undefined
  onStale: any
  constructor(value, validUntil) {
    this.value = value
    this.validUntil = validUntil
  }
  refreshFrom(e: ExpiringResource) {
    this.value = e.value
    this.validUntil = e.validUntil
    this.refreshPromise && (this.refreshPromise.resolve(), (this.refreshPromise = void 0))
  }
  waitForRefresh(e = 10000) {
    this.refreshPromise || (this.refreshPromise = new OpenDeferred())
    const t = funcUtil.waitRun(e).then(() => {
      throw new Error("Waiting for resource url refresh timed out")
    })
    return Promise.race([this.refreshPromise.nativePromise(), t])
  }
  async get() {
    if (this.validUntil && this.onStale) {
      const e = Date.now()
      e + 60000 + 10000 > this.validUntil.getTime() && this.onStale(),
        e + 60000 + 1000 > this.validUntil.getTime() &&
          (a.warn("Stale resource, waiting for refresh"), await this.waitForRefresh(), a.info("Refreshed resource"))
    }
    return this.value
  }
}
